package structure;

import java.util.ArrayList;

import algorithm.utility;

public class enumerateGrammar {

	private ArrayList<String> leftside;
	private ArrayList<String> rightside;
	private String axiom;
	private ArrayList<String> nullable;
	private grammar grammar;
	
	//costruttori
	public enumerateGrammar(){
		
		this.leftside= new ArrayList<String>();
		this.rightside= new ArrayList<String>();
		this.axiom= "";
		this.nullable= null;
		this.grammar= null;
	}
	
	public enumerateGrammar(grammar g){
		
		this.leftside= new ArrayList<String>();
		this.rightside= new ArrayList<String>();
		this.axiom= "";
		this.grammar= g;
		
		if(utility.isThereEproduction(g.getAllProduction()))
			this.nullable= utility.getNullable(g.getAllProduction());
		else
			this.nullable= null;
		
		g.augmentGrammar();
		
		this.axiom= g.getS();
		
		this.expandAndNumerate(g);
	}
	//
	
	private void expandAndNumerate(grammar g){
		
		ArrayList<production> tmpP= g.getAllProduction();
		
		for(production p : tmpP){
			
			String tmpS= p.getLeftSide();
			
			for(String s : p.getRightSide()){
				
				//aggiungo nella stessa posizione in due arraylist diversi il leftside
				//e il right side per avere produzioni singole
				this.leftside.add(tmpS);
				this.rightside.add(s);
			}
		}
	}
	//
	//get
	public ArrayList<String> getLeftside(){
		
		return this.leftside;
	}
	
	public ArrayList<String> getRightside(){
		
		return this.rightside;
	}
	
	public ArrayList<String> getEnumeratedGrammar(){
		
		ArrayList<String> toReturn= new ArrayList<String>();
		
		for(int i=0; i<this.leftside.size(); i++){
			
			String tmpS= this.leftside.get(i) + "->" + this.rightside.get(i);
			toReturn.add(tmpS);
		}
		
		return toReturn;
	}
	
	//restituisce gli indici delle produzioni dove il leftside passato compare 
	public ArrayList<Integer> getLeftsidePosition(String s){

		if(this.leftside.contains(s)){
			ArrayList<Integer> toReturn= new ArrayList<Integer>();
			int size= this.leftside.size();
			for(int i=0; i<size; i++){
				
				String tmpS= this.leftside.get(i);
				if(tmpS.equals(s)){
					toReturn.add(i);
				}
			}
			return toReturn;
		}
		else{
			System.out.println("il leftside "+ s +" non è un leftside della grammatica.");
		}
		
		return null;
	}
	
	//restituisce gli indici delle produzioni dove il leftside passato compare nel rightside
	/*public ArrayList<Integer> getPositionInRightside(String s){

		if(this.leftside.contains(s)){
			ArrayList<Integer> toReturn= new ArrayList<Integer>();
			int size= this.rightside.size();
			
			for(int i=0; i<size; i++){
				
				String tmpS= this.rightside.get(i);
				if(tmpS.contains(s)){
					toReturn.add(i);
				}
			}
			return toReturn;
		}
		else{
			System.out.println("il leftside passato non è un leftside della grammatica.");
		}
		
		return null;
	}*/
	
	public String getAxiom(){
		
		return this.axiom;
	}
	
	public ArrayList<String> getNullable(){
		
		return this.nullable;
	}
	
	public ArrayList<String> getVN(){
		
		return this.grammar.getVN();
	}
	
	public ArrayList<String> getVT(){
		
		return this.grammar.getVT();
	}
	
	public String getProductionByIndex(int index){
		
		String toReturn= this.leftside.get(index) + "->" + this.rightside.get(index);
		
		return toReturn;
	}
	
	//restituisce il numero della produzione in base al rightside
	public int getIndexByRightside(String right){
		
		for(int k=0; k<this.rightside.size(); k++){
			
			if(this.rightside.get(k).equals(right)){
				
				return k;
			}
		}
		
		return -1;
	}
	//
	//set
	
	//
	
	//DEBUG
	
	public void printItAll(){
		
		ArrayList<String> tmpA= this.getEnumeratedGrammar();
		
		for(int i=0; i<tmpA.size(); i++){
			
			System.out.println(Integer.toString(i) + ". " + tmpA.get(i));
		}
	}
}
